home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / AHDI / IDEINST / BOOTSECT.S < prev    next >
Encoding:
Text File  |  2001-02-09  |  9.5 KB  |  301 lines

  1. ; bootsect.s
  2.  
  3. ;------------------------------------------------------------------------
  4. ;                                    :
  5. ; Hard disk partition boot sector                    :
  6. ; Loads SHDRIVER.SYS and executes it.                    :
  7. ;                                    :
  8. ; Copyright 1986, 1987, 1988, 1989, 1990 Atari Corp.            :
  9. ; All Rights Reserved.                            :
  10. ;                                    :
  11. ; Jul-24-1989    ml.    Modified this for the TT.            :
  12. ; Feb-06-1990    ml.    Removed code that handles MSDOS format drive.    :
  13. ;                                    :
  14. ;------------------------------------------------------------------------
  15.  
  16.  
  17. ;---- OS variables:
  18. _sysbase    equ    $4f2    ; (L) -> OS header
  19.  
  20.  
  21. ;+
  22. ;  Branch to executable code (following BPB stuff);
  23. ;  OEM name (which really doesn't matter);
  24. ;  24 bits of (ignored) serial number.
  25. ;
  26. ;-
  27. _bootstart::
  28. base:    bra.s    start        ; branch to code
  29.  
  30. ;+
  31. ;  Space for BPB information
  32. ;  (this is skipped, none of it is written to
  33. ;   the partition's boot sector).
  34. ;
  35. ;  Labels are used as pointers to real bpb info.
  36. ;-
  37.     dc.b    'OEMxxx'    ; filler (OEM cruft)
  38.     dc.b    $00,$00,$00    ; 24-bit serial number (unused)
  39. BPS:    dc.b    $00,$02        ; #bytes/sector
  40. SPC:    dc.b    $02        ; #sectors/cluster
  41. RES:    dc.b    $01,$00        ; #reserved sectors
  42. NFATS:    dc.b    $02        ; #of FATs
  43. NDIRS:    dc.b    $70,$00        ; #of root directory entries
  44. NSECTS:    dc.b    $d0,$02        ; #of sectors on media
  45. MEDIA:    dc.b    $f8        ; media descriptor byte
  46. SPF:    dc.b    $05,$00        ; #sectors/FAT
  47. SPT:    dc.b    $09,$00        ; #sectors/track
  48. NSIDES:    dc.b    $01,$00        ; #sides on media
  49. NHID:    dc.b    $00,$00        ; #hidden sectors
  50.  
  51.  
  52. ;+
  53. ;  Load driver from hard disk:
  54. ;
  55. ;    Passed:    a3.l -> disk read routine
  56. ;        a5.l -> bootstop code
  57. ;        d4.w = devno (if DMAread() is in ROM)
  58. ;            or -1 (if DMAread() is not in ROM)
  59. ;        d6.l = base sector#
  60. ;        d7.b = devno << 5 (if DMAread() doesn't exist in ROM)
  61. ;
  62. ;    - Compute disk parameters (FAT start + length, root
  63. ;      directory start + length).
  64. ;
  65. ;    - Search for driver image in root directory, if
  66. ;      not found then exit.
  67. ;
  68. ;    - Load the driver and execute it.
  69. ;-
  70. start:    moveq    #$48,d3        ; d3 = opcode for Malloc
  71.     moveq    #-1,d0        ; d0 = Malloc(-1L)
  72.     move.l    d0,-(sp)    ;    = size of largest free block
  73.     move.w    d3,-(sp)
  74.     trap    #1
  75.     move.l    d0,d5        ; d5 = # bytes returned (assume >= 512)
  76.     move.l    d0,2(sp)    ; alloc that many bytes
  77.     move.w    d3,(sp)        ; Malloc(that many bytes)
  78.     trap    #1
  79.     addq.w    #6,sp        ; (cleanup stack)
  80.     tst.l    d0        ; successful?
  81.     beq.s    bs_r        ; if not, return
  82.     movea.l    d0,a4        ; a4 -> buffer
  83.  
  84. ;+
  85. ;  Compute disk configuration values
  86. ;
  87. ;  Register usage:
  88. ;    d0     temp in dmaread()
  89. ;    d1     temp in dmaread()
  90. ;    d2.w = # of directory entries;
  91. ;    d3.l = physical starting sector# of FAT0;
  92. ;    d4.w = physical unit # (if DMAread() is in ROM)
  93. ;        or -1 (if DMAread() is not in ROM)
  94. ;    d5     count (=1)
  95. ;    d6.l = physical starting sector# of root directory.
  96. ;    d7.b = devno << 5 (ACSI device number)
  97. ;
  98. ;    a0     temp in dmaread()
  99. ;    a1.l = starting sector# of cluster 2 (the first cluster).
  100. ;    a2.l -> buffer for driver 
  101. ;    a3.l -> disk read procedure
  102. ;    a4.l -> buffer (scratch memory)
  103. ;    a5     temp in dmaread() (if ACSI)
  104. ;    a6     temp in dmaread() (if ACSI)
  105. ;    a7.l   [stack]
  106. ;-
  107.     move.b    BPS+1(pc),d1    ; d1 = log sector size : phys sector size 
  108.     ror.w    #8,d1        ;    = log sector size / 512
  109.     move.b    BPS(pc),d1    
  110.     lsr.w    #8,d1
  111.     lsr.w    #1,d1
  112.  
  113.     moveq    #0,d2        ; d2.l = 8086word(NDIRS)
  114.     move.b    NDIRS+1(pc),d2    ;      = number of root directory entries
  115.     ror.w    #8,d2
  116.     move.b    NDIRS(pc),d2
  117.  
  118.     move.w    RES(pc),d3    ; d3.l = physical starting sector of FAT0
  119.     ror.w    #8,d3        ;      = logical starting sector of FAT0
  120.     mulu    d1,d3        ;    * sector ratio + base sector
  121.     add.l    d6,d3        ;      = 8086word(RES) * d1 + d6
  122.  
  123.     move.w    SPF(pc),d6    ; d6.l = physical starting sector of root dir
  124.     ror.w    #8,d6        ;      = d3 + size of 2 FATs in sectors
  125.     mulu    d1,d6        ;      = d3 + 8086word(SPF) * sector ratio * 2
  126.     add.l    d6,d6
  127.     add.l    d3,d6
  128.  
  129.     lsr.l    #4,d2        ; a1 = physical starting sector of 1st cluster
  130.     add.l    d6,d2        ;    = physical starting sector of root dir
  131.     movea.l    d2,a1        ;    + size of root dir in sectors
  132.                 ;    = d6 + (d2 / 16)
  133.  
  134. ;+
  135. ; Saving the following registers:
  136. ;    d0.l  -> address of buffer allocated        $0(sp).l
  137. ;    d1.lw -> sector size ratio            $6(sp).w
  138. ;    d3.l  = physical starting sector of FAT0    $8(sp).l
  139. ;    d5.l  = # bytes allocated for driver        $c(sp).l
  140. ;-
  141.     movem.l    d0/d1/d3/d5,-(sp) ; save registers (for later)
  142.  
  143. ;+
  144. ;  Read in directory sectors, searching for the
  145. ;  FCB describing the driver file.
  146. ;-
  147. bs_d1:    moveq    #1,d5        ; read 1 sector
  148.     movem.l    a1/a5,-(sp)    ; save a1 and a5
  149.     jsr    (a3)        ; read (next) dir sector
  150.     movem.l    (sp)+,a1/a5    ; restore a1 and a5
  151.     tst.w    d0        ; read successful?
  152.     beq.s    bs_d4        ; if so, go try to find the file
  153. bs_d3:    add.l    d5,d6        ; else ++dir sector number
  154.     cmp.l    a1,d6        ; more directory sector available?
  155.     bcs.s    bs_d1        ; if so, read the next directory sector
  156.                 ; else
  157. ;+
  158. ;  Return to TOS ROM boot loader
  159. ;    - load D7 with magic value to prevent TOS ROMs
  160. ;      from doing any further DMA bus activity.
  161. ;-
  162. bs_rp:    move.w    #$49,-(sp)    ; Mfree(-> buffer allocated)
  163.     trap    #1
  164.     add.w    #$12,sp    
  165. bs_r:    jmp    (a5)
  166.  
  167. ;***************'nnnnnnnneee'
  168. fname:    dc.b    'SHDRIVERSYS'    ; name of driver file
  169.     .even
  170.  
  171. bs_d4:    movea.l    a4,a0        ; a0 -> first FCB
  172.     moveq    #15,d1        ; d1 = number of FCBS - 1 in a directory sector
  173. bs_d5:    moveq    #10,d0        ; d0 = #chars in filename - 1
  174. bs_d6:    move.b    (a0,d0.w),d3    ; get char from FCB
  175.     cmp.b    fname(pc,d0.w),d3 ; compare with fname here
  176.     beq.s    bs_d7        ; if match, try next char
  177.     adda.w    #$20,a0        ; else bump a0 to next FCB
  178.     dbra    d1,bs_d5    ; do more FCBs in current sector if any
  179.     bra.s    bs_d3        ; else try next directory sector
  180. bs_d7:    dbra    d0,bs_d6    ; try for another matching char
  181.                 ; all characters match; Check for enuff memory
  182.     move.l    28(a0),d5    ; d5 = memory needed 
  183.     ror.w    #8,d5        ;    = ceil(size of driver) + 1.5k scratch 
  184.     swap    d5        ;    = size of driver + 0.5k + 1.5k scratch
  185.     ror.w    #8,d5
  186.     addi.l    #$0800,d5    
  187.     cmp.l    $c(sp),d5    ; enough is allocated?
  188.     bhi.s    bs_rp        ; if not, quit
  189.     movea.l    a4,a2        ; a2 -> buffer for driver file
  190.     adda.l    $c(sp),a4    ; a4 -> 1.5k scratch memory
  191.     suba.w    #$600,a4    
  192.     move.w    26(a0),d2    ; D2 = starting cluster# from FCB
  193.     ror.w    #8,d2        ; (8086 wordswap)
  194.  
  195. ;+
  196. ;  Load file into memory
  197. ;    -  read the file in, one cluster at a time
  198. ;-
  199. bsf_rd:    moveq    #-1,d3        ; no FAT sector cached in memory yet
  200.  
  201. ;+
  202. ;  Read (next) cluster
  203. ;
  204. ;  Modified 9-Aug-88 by ML so that the boot code does not rely
  205. ;  on number of sectors per cluster being 2.
  206. ;
  207. ;  Modified 21-Nov-88 by ML to handle partitions with 12-bit FATs
  208. ;  Modified 06-Feb-90 by ML to remove code in handling 12-bit FATs
  209. ;-
  210. bsf_1:    moveq    #0,d5        ; d5 = # physical sectors in a cluster
  211.     move.b    SPC(pc),d5    ;    = # logical sectors in a cluster 
  212.     mulu    $6(sp),d5    ;    * sector ratio
  213.     move    d2,d6        ; d6 = sector# to read (from cluster#)
  214.     subq    #2,d6        ;    = clust# * spc + starting sector of data
  215.     mulu    d5,d6        ;    = (d2 - 2) * d5 + a1
  216.     add.l    a1,d6
  217.     exg    a2,a4        ; swap buffer/file read pointers
  218.  
  219.     movem.l    d2/a1-a2/a5,-(sp) ; save these registers
  220.     jsr    (a3)        ; read (next) dir sector
  221.     movem.l    (sp)+,d2/a1-a2/a5 ; restore these registers
  222.     tst.w    d0        ; read successful?
  223.     bne    bs_rp        ; (pop, then quit on read failure)
  224.     exg    a2,a4        ; swap buffer/file read pointers again
  225.     lsl.l    #8,d5        ; d5 = clustersize in bytes = d5 * 512
  226.     add.l    d5,d5
  227.     adda.l    d5,a2        ; bump file read pointer [clustersize]
  228.     move.w    d2,d6        ; d6 = current cluster number
  229.     ext.l    d6        ; coerce to long
  230.  
  231. ;+
  232. ;  Read in rest of file.
  233. ;  For a 16-bit FAT, there are (512 * 8 / 16 = 256) FAT entries per
  234. ;    sector of FAT.
  235. ;  Get correct FAT cluster into sector buffer
  236. ;-
  237. bsf_16:    lsr.l    #8,d6        ; d6 = sector # for cluster entry
  238.     add.l    8(sp),d6    ;    = (cluster / 256) + starting sector
  239.     cmp.l    d3,d6        ; FAT sector already in buffer?
  240.     beq.s    bsf_2        ; (yes -- get link)
  241.  
  242.     moveq    #1,d5        ; d5 = read count (1 sector)
  243.     move.l    d6,d3        ; d3 = sector# cached in buffer
  244.     movem.l    d2/a1-a2/a5,-(sp) ; save these registers
  245.     jsr    (a3)        ; read (next) dir sector
  246.     movem.l    (sp)+,d2/a1-a2/a5 ; restore these registers
  247.     tst.w    d0        ; read successful?
  248.     bne    bs_rp        ; (pop, then quit on read failure)
  249.  
  250. ;+
  251. ;  Compute next cluster number;
  252. ;  stop reading on end-of-file.
  253. ;-
  254. bsf_2:    andi.w    #$00ff,d2    ; D2 = cluster # from beginning of FAT sector
  255.     add.w    d2,d2        ; *2 to index into table of words
  256.     move.w    (a4,d2.w),d2
  257.     ror.w    #8,d2
  258.     bpl    bsf_1        ; if (D2 != EOF) then read_another_cluster;
  259.  
  260.  
  261. ;+
  262. ;  Validate and execute file
  263. ;    -  check introductory magic in the .PRG header
  264. ;    -  fixup longwords, using the fixup information
  265. ;    -  start execution at `base + 0x20'
  266. ;-
  267. mrl_0:    movea.l    $0(sp),a2    ; a2 -> .PRG header
  268.     movea.l    a2,a0        ; a0 -> there, too
  269.     cmp.w    #$601a,(a0)+    ; if (*a0++ != MAGIC)
  270.     bne    bs_rp        ;    then forget_it;
  271.  
  272. ;+
  273. ;  Compute start of fixup information
  274. ;-
  275.     lea    $1c(a2),a1    ;   a1 -> base of text
  276.     add.l    (a0)+,a1    ;   a1 += tsize
  277.     add.l    (a0)+,a1    ;   a1 += dsize
  278.     add.l    4(a0),a1    ;   a1 += symsize
  279.     tst.l    (a1)        ; if (*a1 == NULL)
  280.     beq.s    mrl_1        ;    then no_fixups_to_do;
  281.  
  282.     lea    $1c(a2),a0    ; a0 -> base of text segment
  283.     move.l    a0,d1        ; d1 -> there, too
  284.     moveq    #0,d0        ; wipe-out upper bits of d0
  285.     add.l    (a1)+,a0    ; a0 -> first fixup
  286.  
  287. mrl_2:    add.l    d1,(a0)        ; add text base to longword at a0
  288. mrl_4:    move.b    (a1)+,d0    ; get next fixup byte
  289.     beq.s    mrl_1        ; if (d0 == 0) we're finished;
  290.     cmp.b    #1,d0        ; if (d0 == 1) a0 += 0xfe;
  291.     bne.s    mrl_3
  292.     add.w    #$00fe,a0
  293.     bra.s    mrl_4
  294. mrl_3:    add.w    d0,a0        ; a0 += d0
  295.     bra.s    mrl_2        ; fixup longword at a
  296.  
  297. mrl_1:    move.l    $c(sp),d0    ; pass #bytes allocated to driver
  298.     adda.w    #$10,sp        ; clean up stack
  299.     jmp    $20(a2)        ; execute file we loaded
  300. _bootend::
  301.